using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Xml.Linq;
using UnityEditor;
using UnityEngine;
using XLua;
using UObject = UnityEngine.Object;

public class LuaManager : MonoBehaviour
{
    //所有Lua文件名 ,用于为预加载提供数据
    public List<string> luaFileNmaes = new List<string>();

    //缓存Lua脚本内容
    private Dictionary<string, byte[]> luaScriptsDic;

    //XLua虚拟机
    public LuaEnv luaEnv;

    private void Update()
    {
        if(luaEnv != null) 
        {
            //lua虚拟机内存回收，释放Lua未使用的内存
            luaEnv.Tick();
        }
    }

    private void OnDestroy()
    {
        //脚本关闭时销毁虚拟机
        if(luaEnv != null) 
        {
            luaEnv.Dispose();
            luaEnv = null;
        }
    }

    public void InitLuaScript()
    {
        luaScriptsDic = new Dictionary<string, byte[]>();

        luaEnv = new LuaEnv();

        luaEnv.AddBuildin("rapidjson", XLua.LuaDLL.Lua.LoadRapidJson);

        luaEnv.AddLoader(Loader);

    #if UNITY_EDITOR
        if (AppConst.GameMode == GameMode.EditorMode)
            EditorLoadLuaScript();
        else
    #endif
            LoadLuaScript();
    }

    public void ExcuteLua(string fileName)
    {
        luaEnv.DoString(string.Format("require '{0}'", fileName));
    }

    #region Lua加载模块

    byte[] Loader(ref string name)
    {
        return GetLuaScript(name);
    }

    //依据Lua文件名获取对应文件
    public byte[] GetLuaScript(string name)
    {
        name = name.Replace(".", "/");
        string fileName = PathUtil.GetLuaPath(name);

        byte[] luaScript = null;
        if(!luaScriptsDic.TryGetValue(fileName, out luaScript))
            Debug.LogError("lua Script is not Exist :" +  fileName);
        return luaScript;
    }

    private void LoadLuaScript()
    {
        foreach (var name in luaFileNmaes)
        {
            Manager.Resources.LoadLua(name, (UObject obj) =>
            {
                AddLuaScript(name, (obj as TextAsset).bytes);
                //缓存的Lua脚本文件大于需要读取的lua文件时说明读取完成
                if (luaScriptsDic.Count >= luaFileNmaes.Count)
                {
                    //初始化完成时调用对应函数
                    Manager.Event.Fire(1);
                    luaFileNmaes.Clear();
                    luaFileNmaes = null;
                }
            });
        }
    }

    private void AddLuaScript(string assetsName, byte[] script)
    {
        luaScriptsDic[assetsName] = script;
    }

#if UNITY_EDITOR
    /// <summary>
    /// 编辑器模式下加载lua文件
    /// </summary>
    private void EditorLoadLuaScript()
    {
        string[] luaFiles = Directory.GetFiles(PathUtil.LuaPath, "*.bytes", SearchOption.AllDirectories);

        for(int i = 0; i < luaFiles.Length; i++) 
        {
            string fileName = PathUtil.GetStandardPath(luaFiles[i]);
            byte[] file = File.ReadAllBytes(fileName);  

            AddLuaScript(PathUtil.GetUnityPath(fileName), file);
        }
        Manager.Event.Fire(1);
    }

#endif
    #endregion
}
